Предварительная загрузка критически важных ресурсов для повышения скорости загрузки.

Когда вы открываете веб-страницу, браузер запрашивает HTML-документ с сервера, анализирует его содержимое и отправляет отдельные запросы на любые указанные ресурсы. Как разработчик, вы уже знаете обо всех ресурсах, которые нужны вашей странице, и какие из них наиболее важны. Вы можете использовать эти знания, чтобы запрашивать критические ресурсы заранее и ускорять процесс загрузки. В этой статье объясняется, как этого добиться с помощью <link rel="preload"> .

Как работает предварительная загрузка

Предварительная загрузка лучше всего подходит для ресурсов, которые браузер обычно обнаруживает поздно.

Скриншот сетевой панели Chrome DevTools.
В этом примере шрифт Pacifico определен в таблице стилей с помощью правила @font-face . Браузер загружает файл шрифта только после завершения загрузки и анализа таблицы стилей.

Предварительно загружая определенный ресурс, вы сообщаете браузеру, что хотели бы загрузить его раньше, чем браузер его обнаружит, поскольку вы уверены, что он важен для текущей страницы.

Скриншот сетевой панели Chrome DevTools после применения предварительной загрузки.
В этом примере шрифт Pacifico предварительно загружен, поэтому загрузка происходит параллельно с таблицей стилей.

Критическая цепочка запросов представляет собой порядок ресурсов, которые приоритизированы и извлекаются браузером. Lighthouse идентифицирует активы, которые находятся на третьем уровне этой цепочки, как поздно обнаруженные. Вы можете использовать аудит запросов ключей предварительной загрузки , чтобы определить, какие ресурсы следует предварительно загрузить.

Аудит запросов на предзагрузку ключа Lighthouse.

Вы можете предварительно загрузить ресурсы, добавив тег <link> с rel="preload" в заголовок вашего HTML-документа:

<link rel="preload" as="script" href="critical.js">

Браузер кэширует предварительно загруженные ресурсы, чтобы они были доступны немедленно при необходимости. (Он не выполняет скрипты и не применяет таблицы стилей.)

Подсказки ресурсов, например, preconnect и prefetch , выполняются по усмотрению браузера. С другой стороны, preload является обязательным для браузера. Современные браузеры уже довольно хорошо расставляют приоритеты ресурсов, поэтому важно использовать preload экономно и загружать только самые важные ресурсы.

Неиспользованные предварительные загрузки вызывают предупреждение консоли в Chrome примерно через 3 секунды после события load .

Предупреждение Chrome DevTools Console о неиспользуемых предварительно загруженных ресурсах.

Варианты использования

Предварительная загрузка ресурсов, определенных в CSS

Шрифты, определенные с помощью правил @font-face , или фоновые изображения, определенные в файлах CSS, не обнаруживаются, пока браузер не загрузит и не проанализирует эти файлы CSS. Предварительная загрузка этих ресурсов гарантирует, что они будут извлечены до загрузки файлов CSS.

Предварительная загрузка CSS-файлов

Если вы используете критический подход CSS , вы разделяете свой CSS на две части. Критический CSS, необходимый для отображения содержимого верхней части страницы, встроен в <head> документа, а некритический CSS обычно загружается с помощью JavaScript. Ожидание выполнения JavaScript перед загрузкой некритического CSS может привести к задержкам в отображении, когда пользователи прокручивают страницу, поэтому хорошей идеей будет использовать <link rel="preload"> чтобы начать загрузку раньше.

Предварительная загрузка файлов JavaScript

Поскольку браузеры не выполняют предварительно загруженные файлы, предварительная загрузка полезна для разделения извлечения от выполнения , что может улучшить такие показатели, как время до интерактивности. Предварительная загрузка работает лучше всего, если вы разделяете свои пакеты JavaScript и предварительно загружаете только критические фрагменты.

Как реализовать rel=preload

Самый простой способ реализовать preload — добавить тег <link> в <head> документа:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Предоставление атрибута as помогает браузеру установить приоритет предварительно выбранного ресурса в соответствии с его типом, установить правильные заголовки и определить, существует ли ресурс уже в кэше. Принятые значения для этого атрибута включают: script , style , font , image и другие .

Некоторые типы ресурсов, такие как шрифты, загружаются в анонимном режиме . Для них необходимо установить атрибут crossorigin с preload :

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Элементы <link> также принимают атрибут type , который содержит тип MIME связанного ресурса. Браузеры используют значение атрибута type , чтобы убедиться, что ресурсы предварительно загружаются только в том случае, если поддерживается их тип файла. Если браузер не поддерживает указанный тип ресурса, он проигнорирует <link rel="preload"> .

Вы также можете предварительно загрузить любой тип ресурса через HTTP-заголовок Link :

Link: </css/style.css>; rel="preload"; as="style"

Преимущество указания preload в заголовке HTTP заключается в том, что браузеру не нужно анализировать документ, чтобы обнаружить его, что в некоторых случаях может обеспечить небольшие улучшения.

Предварительная загрузка модулей JavaScript с помощью webpack

Если вы используете сборщик модулей, который создает файлы сборки вашего приложения, вам нужно проверить, поддерживает ли он внедрение тегов предварительной загрузки. С версией webpack 4.6.0 или более поздней предварительная загрузка поддерживается с помощью магических комментариев внутри import() :

import(_/* webpackPreload: true */_ "CriticalChunk")

Если вы используете старую версию Webpack, используйте сторонний плагин, например preload-webpack-plugin .

Влияние предварительной загрузки на основные веб-показатели

Предварительная загрузка — это мощная оптимизация производительности, которая влияет на скорость загрузки. Такие оптимизации могут привести к изменениям в Core Web Vitals вашего сайта, и важно знать о них.

Самая большая содержательная краска (LCP)

Предварительная загрузка оказывает сильное влияние на отрисовку самого большого содержимого (LCP) , когда речь идет о шрифтах и ​​изображениях, поскольку кандидатами LCP могут быть как изображения, так и текстовые узлы. Главные изображения и большие фрагменты текста, которые визуализируются с использованием веб-шрифтов, могут значительно выиграть от хорошо размещенной подсказки предварительной загрузки и должны использоваться, когда есть возможность доставить эти важные фрагменты содержимого пользователю быстрее.

Однако вы должны быть осторожны, когда дело касается предварительной загрузки и других оптимизаций! В частности, избегайте предварительной загрузки слишком большого количества ресурсов. Если слишком много ресурсов приоритетны, то фактически ни один из них не приоритетен. Эффект от чрезмерных подсказок предварительной загрузки будет особенно пагубным для тех, кто использует более медленные сети, где конкуренция за пропускную способность будет более очевидной.

Вместо этого сосредоточьтесь на нескольких высокоценных ресурсах, которые, как вы знаете, выиграют от удачно размещенной предварительной загрузки. При предварительной загрузке шрифтов убедитесь, что вы обслуживаете шрифты в формате WOFF 2.0, чтобы максимально сократить время загрузки ресурсов. Поскольку WOFF 2.0 имеет отличную поддержку браузеров , использование старых форматов, таких как WOFF 1.0 или TrueType (TTF), задержит ваш LCP, если кандидат LCP является текстовым узлом.

Когда дело доходит до LCP и JavaScript, вам нужно убедиться, что вы отправляете полную разметку с сервера, чтобы сканер предварительной загрузки браузера работал правильно. Если вы обслуживаете опыт, который полностью полагается на JavaScript для рендеринга разметки и не может отправлять HTML, рендеренный сервером, было бы выгодно вмешаться там, где сканер предварительной загрузки браузера не может, и предварительно загрузить ресурсы, которые в противном случае были бы обнаружены только после завершения загрузки и выполнения JavaScript.

Накопительный сдвиг компоновки (CLS)

Накопительный сдвиг макета (CLS) является особенно важной метрикой, когда речь идет о веб-шрифтах, и CLS имеет значительное взаимодействие с веб-шрифтами, которые используют свойство CSS font-display для управления загрузкой шрифтов. Чтобы минимизировать сдвиги макета, связанные с веб-шрифтами, рассмотрите следующие стратегии:

  1. Предварительно загружать шрифты, используя значение block по умолчанию для font-display . Это тонкий баланс. Блокирование отображения шрифтов без отката можно считать проблемой пользовательского опыта. С одной стороны, загрузка шрифтов с помощью font-display: block; устраняет сдвиги макета, связанные с веб-шрифтами. С другой стороны, вы все равно хотите, чтобы эти веб-шрифты загружались как можно скорее, если они имеют решающее значение для пользовательского опыта. Объединение предварительной загрузки с font-display: block; может быть приемлемым компромиссом.
  2. Предварительно загружать шрифты, используя fallback значение для font-display . fallback — это компромисс между swap и block , поскольку оно имеет чрезвычайно короткий период блокировки.
  3. Используйте optional значение для font-display без предварительной загрузки. Если веб-шрифт не имеет решающего значения для пользовательского опыта, но все равно используется для отображения значительного объема текста страницы, рассмотрите возможность использования optional значения. В неблагоприятных условиях optional будет отображать текст страницы в резервном шрифте, пока оно загружает шрифт в фоновом режиме для следующей навигации. Конечным результатом в этих условиях является улучшенный CLS, поскольку системные шрифты будут отображаться немедленно, в то время как последующие загрузки страниц будут загружать шрифт немедленно без сдвигов макета.

CLS — это сложная метрика для оптимизации, когда дело касается веб-шрифтов. Как всегда, экспериментируйте в лаборатории , но доверяйте своим полевым данным , чтобы определить, улучшают ли ваши стратегии загрузки шрифтов CLS или ухудшают его.

Взаимодействие со следующей покраской (INP)

Взаимодействие с Next Paint — это метрика, которая измеряет реакцию на пользовательский ввод. Поскольку львиная доля интерактивности в Интернете управляется JavaScript, предварительная загрузка JavaScript, которая обеспечивает важные взаимодействия, может помочь снизить INP страницы. Однако имейте в виду, что предварительная загрузка слишком большого количества JavaScript во время запуска может иметь непреднамеренные негативные последствия, если слишком много ресурсов конкурируют за пропускную способность.

Вам также следует быть осторожным с тем, как вы подходите к разделению кода . Разделение кода — это отличная оптимизация для сокращения объема JavaScript, загружаемого во время запуска, но взаимодействия могут задерживаться, если они полагаются на JavaScript, загруженный прямо в начале взаимодействия. Чтобы компенсировать это, вам нужно будет изучить намерение пользователя и ввести предварительную загрузку для необходимого фрагмента(ов) JavaScript до того, как произойдет взаимодействие. Одним из примеров может быть предварительная загрузка JavaScript, необходимая для проверки содержимого формы, когда любое из полей в форме находится в фокусе.

Заключение

Чтобы повысить скорость загрузки страницы, предварительно загружайте важные ресурсы, которые браузер обнаруживает с опозданием. Предварительная загрузка всего будет контрпродуктивной, поэтому используйте preload экономно и измеряйте ее влияние в реальном мире .